﻿using System;
using System.Collections.Generic;
using System.ServiceProcess;
using WindowServices.Common;
using System.IO;
using System.Linq;
using WindowServices.Server.Interface;
using WindowServices.Service.Command;
using System.Threading;
using WindowServices.Service.Properties;

namespace WindowServices.Service
{
    public partial class Services : ServiceBase
    {
        readonly Dictionary<string, ServiceHelper> _services = new Dictionary<string, ServiceHelper>();
        
        public Services()
        {
            InitializeComponent();
            AutoLog = true;
        }

#if(!DEBUG1)
        protected override
#else
        public new
#endif
 void OnStart(string[] args)
        {
            StartWork(new LoadServiceCommand(_services, Common.ServiceHelper.GetAllServiceEntity()));
        }

        private static void StartWork(ICommand command)
        {
            if(command == null)
            {
                return;
            }

            var thread = new Thread(WorkThread);
            thread.Start(command);
        }
        private static void WorkThread(object command)
        {
            if (!(command is ICommand))
            {
                return;
            }

            var invokeCommand = new InvokeCommand();
            invokeCommand.SetCommand(command as ICommand);
            invokeCommand.Execute();
        }
        protected override void OnStop()
        {
            StartWork(new UnLoadServiceCommand(_services));
        }

        protected override void OnShutdown()
        {
            StartWork(new UnLoadServiceCommand(_services));
        }

        protected override void OnCustomCommand(int command)
        {
            List<ServiceEntityEx> list = null;
            try
            {
                using (var config = new TempServiceConfig(false))
                {
                    list = config.GetAllServiceEntity();
                }
                if (list.Count == 0)
                {
                    return;
                }

                base.OnCustomCommand(command);
                var invokeCommand = new InvokeCommand();
                switch ((ServiceCommand)command)
                {
                    case ServiceCommand.Add:
                        invokeCommand.SetCommand(new SetupCommand(_services, list[0]));
                        break;
                    case ServiceCommand.Update:
                        var old = Common.ServiceHelper.GetAllServiceEntity().FirstOrDefault(c => c.Id == list[0].Id);
                        if (old == null)
                        {
                            throw new Exception(string.Format(Resources.ServiceIsNotExistsOrDelete, list[0].Name));
                        }

                        invokeCommand.SetCommand(new UpdateCommand(_services, list[0], old));

                        if (File.Exists(old.ZipFileName))
                        {
                            File.Delete(old.ZipFileName);
                        }

                        break;
                    case ServiceCommand.Delete:
                        invokeCommand.SetCommand(new UnInstallCommand(_services, list[0]));
                        break;
                }

                invokeCommand.Execute();
            }
            catch (Exception exception)
            {
                if (list != null && (ServiceCommand)command != ServiceCommand.Delete)
                {
                    list.ForEach(c =>
                {
                    if (File.Exists(c.ZipFileName))
                    {
                        File.Delete(c.ZipFileName);
                    }
                });
                }

                LogHelper.WriteEntityServiceError(string.Format(Resources.ExcuteUpdateCommandError,exception), EventType.Info);
            }
            finally
            {
                if (File.Exists(TempServiceConfig.ConfigFile))
                {
                    File.Delete(TempServiceConfig.ConfigFile);
                }
            }

        }
    }
}
